﻿namespace TopHero
{
    public class Monster : BaseEntity
    {
        private IViewObject _viewObject;
        private readonly Game _game;
        public World world => _game.world;
        private StateMachine<Monster> _stateMachine;
        public StateMachine<Monster> stateMachine => _stateMachine;

        private PropertyManager _propertyManager;

        public Monster(Game game)
        {
            _game = game;
            _stateMachine = new StateMachine<Monster>(this);
            _stateMachine.ChangeState(MonsterIdleState.Instance);

            InitProperty();

            EntityManager.Instance.RegisterEntity(this);
        }

        private void InitProperty()
        {
            _propertyManager = new PropertyManager();
            Property maxHp = _propertyManager.AddProperty(PropertyId.MAX_HP, 50);
            Property hpRate = _propertyManager.AddProperty(PropertyId.HP_RATE, 0);
            Property hp = _propertyManager.AddBasePercentProperty(PropertyId.HP, 50, maxHp, hpRate, maxHp);

            Property atk = _propertyManager.AddProperty(PropertyId.ATK, 5);

            Property maxSpeed = _propertyManager.AddProperty(PropertyId.MAX_SPEED, 1.5f);
            Property speedRate = _propertyManager.AddProperty(PropertyId.SPEED_RATE, 1);
            Property speed =
                _propertyManager.AddBasePercentProperty(PropertyId.SPEED, 0, maxSpeed, speedRate, maxSpeed);
        }

        internal override void Start()
        {
            _viewObject = _game.viewService.CreatePrefabView(2);
            _viewObject.Link(this);
        }

        internal override void Update()
        {
            if (!Dead())
            {
                _propertyManager.Update();
                _stateMachine.Update();
            }
        }

        internal override void Destroy()
        {
            _viewObject.Unlink();
            EntityManager.Instance.RemoveEntity(this);
        }

        internal override bool HandleMessage(Telegram telegram)
        {
            if (_stateMachine.HandleMessage(telegram))
            {
                return true;
            }

            return false;
        }

        internal bool Dead()
        {
            return _propertyManager.GetValue(PropertyId.HP) <= 0;
        }

        public void SetPropertyValue(int id, float value)

        {
            Property property = _propertyManager.GetProperty(id);
            property.value = value;
        }

        public float GetPropertyValue(int id)
        {
            return _propertyManager.GetValue(id);
        }
    }
}